﻿#include "windows.h"
#include <iostream>  
#include <TCHAR.H>   
#include <string.h>

using namespace std;

HANDLE hCom; //全局变量，串口句柄

int serial_open(LPCWSTR COMx, int BaudRate) {
	BOOL bSetCommState;

	hCom = CreateFile(COMx, //COM1口    
		GENERIC_READ | GENERIC_WRITE, //允许读和写    
		0, //独占方式    
		NULL,
		OPEN_EXISTING, //打开而不是创建     
		0, //重叠方式FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED  (同步方式设置为0)
		NULL);
	if (hCom == INVALID_HANDLE_VALUE)
	{
		printf("打开COM失败!\n");
		return FALSE;
	}
	SetupComm(hCom, 1024, 1024); //输入缓冲区和输出缓冲区的大小都是1024 

								 //设定读写超时 
								 /*COMMTIMEOUTS TimeOuts;
								 TimeOuts.ReadIntervalTimeout=1000;
								 TimeOuts.ReadTotalTimeoutMultiplier=500;
								 TimeOuts.ReadTotalTimeoutConstant=5000; //设定写超时
								 TimeOuts.WriteTotalTimeoutMultiplier=500;
								 TimeOuts.WriteTotalTimeoutConstant = 2000;
								 SetCommTimeouts(hCom, &TimeOuts); //设置超时
								 */
	DCB dcb;
	GetCommState(hCom, &dcb);
	dcb.BaudRate = BaudRate;		//设置波特率为BaudRate
	dcb.ByteSize = 8;				//每个字节有8位 
	dcb.Parity = NOPARITY;			//无奇偶校验位 
	dcb.StopBits = ONESTOPBIT;		//一个停止位
	bSetCommState = SetCommState(hCom, &dcb);		//设置参数到hCom

	if (!bSetCommState)
	{
		printf("设置串口失败!\n");
		return FALSE;
	}

	PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);//清空缓存区		//PURGE_TXABORT 中断所有写操作并立即返回，即使写操作还没有完成。
												   //PURGE_RXABORT 中断所有读操作并立即返回，即使读操作还没有完成。
												   //PURGE_TXCLEAR 清除输出缓冲区 
												   //PURGE_RXCLEAR 清除输入缓冲区 

	printf("打开串口成功!\n");
	return TRUE;
}
int serial_write(char lpOutBuffer[], DWORD length)	//同步写串口
{
	DWORD dwBytesWrite = length;
	DWORD dwBytesWriten = 0;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	BOOL bWriteStat;
	ClearCommError(hCom, &dwErrorFlags, &ComStat);
	bWriteStat = WriteFile(hCom, lpOutBuffer, dwBytesWrite, &dwBytesWriten, NULL);
	if (!bWriteStat)
	{
		printf("写串口失败!\n");
		return FALSE;
	}
	PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
	return TRUE;
}
void Serial_close(void)		//关闭串口
{
	printf("关闭串口!\n");
	CloseHandle(hCom);
}
int main()
{
	char openOrder[] = {0xA5, 0x08, 0x00, 0xA1, 0x01, 0x05, 0x00, 0x00, 0xFF, 0xEE, 0x5A}; //打开呼吸灯
	char yellowOrder[] = {0xA5, 0x0B, 0xFF, 0xA1, 0x02, 0x07, 0x64, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x5A}; //打开黄灯爆闪灯
	char redOrder[] = {0xA5, 0x08, 0xFF, 0xA1, 0x02, 0x01, 0x3C, 0x02, 0xFF, 0xEE, 0x5A}; //打开红灯爆闪灯
	char yellowBLNOrder[] = {0xA5, 0x08, 0xFF, 0xA1, 0x01, 0x01, 0x0A, 0x00, 0xFF, 0xEE, 0x5A}; //打开黄呼吸灯	
	char redBLNOrder[] = {0xA5, 0x08, 0xFF, 0xA1, 0x01, 0x06, 0x0A, 0x00, 0xFF, 0xEE, 0x5A}; //打开红呼吸灯
	char closeOrder[] = {0xA5, 0x08, 0x00, 0xA1, 0x01, 0x05, 0x00, 0x00, 0x00, 0xEE, 0x5A}; //关闭呼吸灯
	unsigned int select;

	serial_open(_T("COM5"), 9600); //打开COM1，波特率为4800

	while (1)
	{
		printf("打开呼吸灯(1), 黄灯爆闪(2), 红灯爆闪(3), 红灯呼吸灯(4), 黄灯呼吸灯(5)， 关闭呼吸灯(6), 退出(5)\n");
		scanf_s("%d", &select);

		if (select == 1)
		{
			serial_write(openOrder, 11);
		}
		else if (select == 2)
		{
			serial_write(yellowOrder, 14);
		}
		else if (select == 3)
		{
			serial_write(redOrder, 11);
		}
		else if (select == 4)
		{
			serial_write(redBLNOrder, 11);
		}
		else if (select == 5)
		{
			serial_write(yellowBLNOrder, 11);
		}
		else if (select == 6)
		{
			serial_write(closeOrder, 11);
		}
		else if (select == 7)
		{
			break;
		}
	}
	
	Serial_close();//关闭串口
	system("pause");
	return 0;
}
